package com.boxin.ims.modules.html.utils;

import java.net.URL;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import com.thinkgem.jeesite.common.utils.StringUtils;


/**
 * @author Jakemanse
 * @date 2014-1-10
 * @function <p> Html 工具类 </p>
 */
public class HtmlUtils {
	
	/**
	 * @author Jakemanse
	 * @time 2014-1-10  上午9:56:04
	 * @function <p> 获取HTML 内容 </p>
	 * @param siteUrl
	 * @return
	 * @throws Exception
	 */
	public static String getHtmlContent(String siteUrl) throws Exception {
		URL url = new URL(siteUrl);
		Document htmlDoc = 	Jsoup.parse(url, 60000);
		if(htmlDoc != null)	return htmlDoc.html();
		
		return null;
		
	}
	
	/**
	 * @author Jakemanse
	 * @time 2014-1-10  上午10:01:03
	 * @function <p> 获取HTML Document </p>
	 * @param siteUrl
	 * @return
	 * @throws Exception
	 */
	public static Document getHtmlDocument(String siteUrl) throws Exception{
		URL url = new URL(siteUrl);
		Document htmlDoc = 	Jsoup.parse(url, 60000);
		return htmlDoc;
	}
	/**
	 * @author Jakemanse
	 * @time 2014-1-15  下午4:09:01
	 * @function <p> 根据URL和css直接获取 元素、标签集合 </p>
	 * @param url
	 * @param cssQuery
	 * @return
	 */
	public static Elements selectElementsByUrlCss(String url,String cssQuery){
		try {
			
			Document htmlDoc = 	getHtmlDocument(url);
			return htmlDoc.select(cssQuery);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		
	}
	
	
	/**
	 * @author Jakemanse
	 * @time 2014-1-10  上午10:04:31
	 * @function <p>  </p>
	 * @param htmlDoc
	 * @param css
	 * @return
	 */
	public static Elements getDivElementsWithClass(Document htmlDoc,String css){
		
		try {
			if(!css.startsWith(".")){
				css = "."+css;
			}
			htmlDoc.select(css + " div");
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
	public static String convertTableToPre(String tableStr){
		tableStr = Jsoup.parse(tableStr).body().html();
		tableStr = RegexUtil.replace("\n\\s*", "", tableStr, RegexUtil.CASE_INSENSITIVE);
		tableStr = RegexUtil.replace("\n", "", tableStr, RegexUtil.CASE_INSENSITIVE);
		tableStr = RegexUtil.replace("(<P>)?(?:&#160;)*\\s*<table[^>]*>", "<table border=1>", tableStr, RegexUtil.CASE_INSENSITIVE);
		tableStr = RegexUtil.replace("</table>\\s*</p>", "</table>", tableStr, RegexUtil.CASE_INSENSITIVE);
		tableStr = RegexUtil.replace("(<(?:tr))([^<>]*)(>)", "$1$3", tableStr, RegexUtil.CASE_INSENSITIVE);
		tableStr = RegexUtil.replace("<p(?!\\w)[^<>]*?>([\\s\\u00a0]|&nbsp;|&#160;)*</p(?!\\w)[^<>]*?>(?=([\\s\\S](?!<td(?!\\w)))*?</td(?!\\w))"," ", tableStr,RegexUtil.CASE_INSENSITIVE);
		tableStr = RegexUtil.replace("<td>\\s*([^\\s]*)\\s*</td>", "<td>$1</td>", tableStr, RegexUtil.CASE_INSENSITIVE);
	
//		tableStr = RegexUtil.replace("<P>(?:&#160;)*\\s*<table[^>]*>", "<table border=1>", tableStr, RegexUtil.CASE_INSENSITIVE);
//		tableStr = RegexUtil.replace("</table>\\s*</p>", "</table>", tableStr, RegexUtil.CASE_INSENSITIVE);
//		tableStr = RegexUtil.replace("<table.*?/table>", "</table>", tableStr);
//		Pattern pattern = Pattern.compile("<table.*?/table>", Pattern.CASE_INSENSITIVE);
//		Matcher matcher = pattern.matcher(tableStr);
//		List<String> strings = new ArrayList<String>();
//		while (matcher.find()) {
//			String tableContent = matcher.group();
//			FileUtils.writeFile(Constants.SYS.PATH_TEMP+MD5Utils.getMD5String(tableContent), tableContent);
//			strings = ShellCommand.execute("w3m -dump -T text\\/html "+Constants.SYS.PATH_TEMP+MD5Utils.getMD5String(tableContent));
//			//ShellCommand.execute(strings);
//		}
		
		return tableStr;
	}
	/**
	 *  处理页码问题
	 * 
	 */
	public static String formatHtmlPages(String content){
		content = RegexUtil.replace("<span class=\"(Sup2?)\">\\s*([0-9\\*\\-\\†]+)\\s+", "<span class=\"$1\">$2</span>", content, RegexUtil.CASE_INSENSITIVE);
		content = RegexUtil.replace("([a-z])\\-<br[^<>]*>", "$1", content,RegexUtil.CASE_INSENSITIVE);
		content = RegexUtil.replace("&nbsp;", " ", content, RegexUtil.CASE_INSENSITIVE);
		content = RegexUtil.replace("<div>", "<p>", content, RegexUtil.CASE_INSENSITIVE);
		content = RegexUtil.replace("</div>", "<p/>", content, RegexUtil.CASE_INSENSITIVE);
		content = RegexUtil.replace("CONSOLIDATED\\s*WITH:", "", content);
		content = RegexUtil.replace("O\\s*R\\s*D\\s*E\\s*R", "ORDER", content);
		content = RegexUtil.replace("D\\s+E\\s*C\\s*I\\s*S\\s*I\\s*O\\s*N", "DECISION", content);
		content = RegexUtil.replace("U\\s*N\\s*P\\s*U\\s*B\\s*L\\s*I\\s*S\\s*H\\s*E\\s*D\\s*O\\s*P\\s*I\\s*N\\s*I\\s*O\\s*N", "UNPUBLISHED OPINION", content);
		content = RegexUtil.replace("\\,+", ",", content, RegexUtil.CASE_INSENSITIVE);
		content = RegexUtil.replace("B\\s+e\\s+f\\s+o\\s+r\\s+e", "Before", content);
		Document document = Jsoup.parse(content);
		String text = "";
		//处理页码
		StringBuffer sb = new StringBuffer();
		List<org.jsoup.nodes.Node> nodes = document.body().childNodes();
		for(org.jsoup.nodes.Node node : nodes){
			sb.append(node.toString());
		}
		text = sb.toString();
//		text = StringUtils.escapeQuote(text);
		String[]modeRealPage = new String[]{"(\\d+)\\.?","(?:page(?:\\s|<[^<>]*>)*(\\d+)(?:\\s|<[^<>]*>)*of(?:\\s|<[^<>]*>)*\\d+)","(\\d+)","(\\d+)\\s*/\\s*\\d+","(?:page(?:\\s|<[^<>]*>)*(\\d+))"};
		Boolean boo = false;//默认在上面
		Pattern pattern = Pattern.compile("<hr\\s*/?>");
		Matcher matcher =pattern.matcher(text);
		
		//如果是页码在内容下边
		sb = new StringBuffer();
		String pageKey = null;
		for(String modePage : modeRealPage){
			String mode = "";
			mode = "<p[^<>]*>(?:<(?!/?table)[^<>]*>|\\s|\\-)*"+modePage+"(?:<(?!/?table)[^<>]*>|\\s|\\-)*?(<hr\\s?\\/?>|$)";
			pattern = Pattern.compile(mode,Pattern.CASE_INSENSITIVE|Pattern.UNICODE_CHARACTER_CLASS);
			matcher =pattern.matcher(text);
			if(matcher.find()){
				text = text +"<hr>";
				pageKey = mode;
				boo = true;
			}
		}
		
		// 如果是页码在内容上面
		for(String modePage : modeRealPage){
			String mode = "";
			mode = "<hr\\s*?/?>(?:<(?!/?table)[^<>]*>|\\s|\\-)*"+modePage+"(?:\\s|<(?!/?(table|tr|td))[^<>]*>|\\-)*?</p>";
			pattern = Pattern.compile(mode,Pattern.CASE_INSENSITIVE);
			matcher =pattern.matcher(text);
			if(matcher.find()){
				text = text +"<hr>";
				pageKey = mode;
				boo = false;
			}
		}
		if(null != pageKey){
			if(boo){
				text = RegexUtil.replace("\n\\s*", "", text, RegexUtil.CASE_INSENSITIVE);
				text = RegexUtil.replace("\n", "", text, RegexUtil.CASE_INSENSITIVE);
				text = RegexUtil.replace("<p>\\s*</p>", "", text, RegexUtil.CASE_INSENSITIVE);
//				text = RegexUtil.replace(pageKey, "<p page=''>Page $1</p><hr>", text, RegexUtil.CASE_INSENSITIVE);
				text = RegexUtil.replace(pageKey, "<p page=''>Page $1</p><hr>", text, RegexUtil.CASE_INSENSITIVE);
				text = RegexUtil.replace("<hr\\s?\\/?>(.*?)(<p page=\\'\\'>Page \\d+</p>)", "<hr>$2$1", text, RegexUtil.CASE_INSENSITIVE);
			}else{
				text = RegexUtil.replace(pageKey, "<hr><p page=''>Page $1</p>", text,RegexUtil.CASE_INSENSITIVE);
			}
		}
		
		return text;
	}
	
//	/**
//	 * 抽取注释 
//	 * 
//	 */
//	public static String extractHtmlSup(String content){
//		//抽取注释
//		String htmlContent = content;
//		htmlContent = htmlContent.replaceAll("=====\\s*</sup>", "</sup>=====");
//		htmlContent = RegexUtil.replace("\n\\s*", "", htmlContent, RegexUtil.CASE_INSENSITIVE);
//		htmlContent = RegexUtil.replace("\n", "", htmlContent, RegexUtil.CASE_INSENSITIVE);
//		String modenode = "=====(.*?)(<p page=\\\"\\\">Page|<hr>|$)";
//		Map<Integer, String[]> tempNodeMaps=  RegexUtil.matchAll(modenode, htmlContent, RegexUtil.CASE_INSENSITIVE|RegexUtil.MULTILINE);
//		StringBuilder nodeStringBuilder = new StringBuilder();
//		for (String nodeKey : tempNodeMaps.get(1)) {
//			Whitelist whitelist = new Whitelist();
//			whitelist.addTags("p","sqan","table","tbody","tr","td","sup","b","a","u","i","strike","s");
//			whitelist.addAttributes("td", "colspan");
//			nodeKey = RegexUtil.replace("<strike>", "<s>",nodeKey, RegexUtil.CASE_INSENSITIVE);
//			nodeKey = RegexUtil.replace("</strike>", "</s>",nodeKey, RegexUtil.CASE_INSENSITIVE);
//			String nodeStr = Jsoup.clean(nodeKey, whitelist).replaceAll("\n", "").replaceAll("<table>", "<table border='1'>");
//			nodeStr = RegexUtil.replace("<td>\\s*<\\/td>", "<td>&nbsp;<\\/td>", nodeStr);
//			nodeStringBuilder.append(nodeStr);
//		}
//		String htmlNode = nodeStringBuilder.toString();
//		htmlNode = RegexUtil.replace("<p(?!\\w)[^<>]*?>([\\s\\u00a0]|&nbsp;|&#160;)*</p(?!\\w)[^<>]*?>(?=([\\s\\S](?!<td(?!\\w)))*?</td(?!\\w))","", htmlNode,RegexUtil.CASE_INSENSITIVE);
//		htmlNode = RegexUtil.replace("<td>\\s*([^\\s]*)\\s*</td>", "<td>$1</td>", htmlNode, RegexUtil.CASE_INSENSITIVE);
//		htmlNode = RegexUtil.replace("<p>\\s*?</p>", "", htmlNode, RegexUtil.CASE_INSENSITIVE);
//		htmlNode = RegexUtil.replace("</?a[^<>]*>", "", htmlNode, RegexUtil.CASE_INSENSITIVE);
//		while (StringUtils.isNotBlank(RegexUtil.match("<p[^<>]*>.*?(<sup[^<>]*>(.*?)</sup><sup[^<>]*>(.*?)</sup>)", htmlNode, RegexUtil.CASE_INSENSITIVE))) {
//			htmlNode = RegexUtil.replace("(<p[^<>]*>.*?)<sup[^<>]*>(.*?)</sup><sup[^<>]*>(.*?)</sup>", "$1<sup>$2$3</sup>", htmlNode, RegexUtil.CASE_INSENSITIVE);
//		}
//		htmlContent = RegexUtil.replace(modenode, "", htmlContent, RegexUtil.CASE_INSENSITIVE);
//		//替换注释
//		modenode = "<sup>(?:\\s|<[^<>]*>)*[^0-9\\*\\-\\†]?([0-9\\*\\-\\†]{1,9})[^0-9\\*\\-\\†]?(?:\\s|<[^<>]*>)*</sup>";
//		htmlContent = RegexUtil.replace(modenode, "<span class=\"Sup\">$1</span>", htmlContent, RegexUtil.CASE_INSENSITIVE);
//		modenode = "<span class=\\\"sup\\\">([^<>]{1,9})</span>";
//		Map<Integer, String[]> modeNodeMaps = RegexUtil.matchAll(modenode, htmlContent, RegexUtil.CASE_INSENSITIVE);
//		if(modeNodeMaps != null && modeNodeMaps.size() >0){
//			for(int i = 0;i<modeNodeMaps.get(1).length;i++){
//				String modebuttomsup1= "<p[^<>]*>((?:<[^<>]*>|\\s)*)("+StringUtils.escapeRegex(modeNodeMaps.get(1)[i])+")([^0-9\\*\\-\\†]+)";
//				String modebuttomsup2 = "<p[^<>]*>((?:<(?![^<>]*?Sup2)[^<>]*>|\\s)*)<sup>("+StringUtils.escapeRegex(modeNodeMaps.get(1)[i])+")([^0-9\\*\\-\\†]+)";
//				
//				Pattern pattern = Pattern.compile(modebuttomsup2, Pattern.CASE_INSENSITIVE);
//				Matcher matcher = pattern.matcher(htmlNode);
//				if (matcher.find()) {
//					htmlNode = matcher.replaceFirst("<p>$1<span class=\"Sup2\">$2</span>$3");
//				}else {
//					pattern = Pattern.compile(modebuttomsup1, Pattern.CASE_INSENSITIVE);
//					matcher = pattern.matcher(htmlNode);
//					if (matcher.find()) {
//						htmlNode = matcher.replaceFirst("<p>$1<span class=\"Sup2\">$2</span>$3");
//					}
//				}
//			}
//		}
//		
//		htmlNode = RegexUtil.replace("<p>\\s*?</p>", "", htmlNode, RegexUtil.CASE_INSENSITIVE);
////		htmlNode = htmlNode.replace("</sup>", "");
//		//补回sub标签
//		htmlContent = addSubTag(htmlContent);
//		Elements elements= Jsoup.parse(htmlNode).select("p");
//		int n=0;
//		for(Element ele:elements){
//			if("".equals(RegexUtil.match("<sup>.*</sup>", ele.html(), RegexUtil.CASE_INSENSITIVE))
//			   &&"".equals(RegexUtil.match("<span class=\"Sup\\d\"?>(.*?)</span>", ele.html(), RegexUtil.CASE_INSENSITIVE))){
//				continue;
//			}
//			String subStr = RegexUtil.match("<span class=\"Sup\\d\"?>(.*?)</span>", ele.html(), RegexUtil.CASE_INSENSITIVE);
//			Map<Integer,String[]> supNumMaps = RegexUtil.matchAll("<span class=\"Sup\\d\"?>(.*?)</span>", ele.html());
//			String[] supNumArray = supNumMaps.get(1);
//			String supNum ="";
//			if(supNumArray.length!=0){
//				supNum =supNumArray[0];
//			}else{
//				Map<Integer,String[]> othersupNumMaps = RegexUtil.matchAll("<sup>(\\d+?)</sup>", ele.html());
//				String[] othersupNumArray = othersupNumMaps.get(1);
//				supNum =othersupNumArray[0];
//			}
//		    htmlNode = RegexUtil.replace(subStr, 
//								"<a name=\"#bookmark"+n+"\"><sup>"+supNum+"</sup></a>", 
//								htmlNode,
//								RegexUtil.CASE_INSENSITIVE);
//			n++;
//		}
//		return htmlContent +"<p>_______________________________________________</p>"+htmlNode;
//	}
	


	
	/**
	 * 匹配数量 
	 */
	public static Integer substrCount(String html,String mode){
		Integer sbnum = 0;
		Pattern pattern = Pattern.compile(mode,Pattern.CASE_INSENSITIVE);
		Matcher matcher = pattern.matcher(html);
		while(matcher.find()){
			sbnum ++;
		}
		return sbnum;
	}


	
	/**
	 * 抽取注释 
	 * 
	 */
	
	
	
	public static String formatPageAndSup(String tag1,String value,String tag2){
		Pattern pattern = Pattern.compile("page",Pattern.CASE_INSENSITIVE);
		Matcher matcher = pattern.matcher(tag1);
		value = RegexUtil.replace("&sect;", "§", value);
		value = value.trim();
		if(matcher.find()){
			return tag1+value.replaceAll("\\D", "")+"</"+tag2+">";
		}else{
//			return tag1+value+"</"+tag2+">";
			if(StringUtils.isNotBlank(RegexUtil.match("[0-9\\*\\-\\†\\‡\\§]+", value))){
				return tag1+value+"</"+tag2+">";
			}else {
				return "[sup "+value+"]";
			}
//			return tag1+value.replaceAll("[^0-9\\*\\-\\†]", "")+"</"+tag2+">";
		}
	}
	
	
	/**
	 * 检测CaseHtml
	 *  
	 */
	
	
	
	/**
	 * 处理[br]标签 
	 */
	public static String bbTagToHtmlBR(String html){
		String mode = "<p[^<>]*>(?:&#160;)*(?:<[^>]+>)*\\[\\s*br\\s*\\](?:<[^>]+>)*</p>";
		Pattern pattern = Pattern.compile(mode,Pattern.CASE_INSENSITIVE);
		Matcher matcher = pattern.matcher(html);
		StringBuffer sb = new StringBuffer();
		while(matcher.find()){
			matcher.appendReplacement(sb, "<br>");
		}
		matcher.appendTail(sb);
		html = sb.toString();
		
		mode = "\\[br\\]";
		pattern = Pattern.compile(mode,Pattern.CASE_INSENSITIVE);
		matcher = pattern.matcher(html);
		sb = new StringBuffer();
		while(matcher.find()){
			matcher.appendReplacement(sb, "<br>");
		}
		matcher.appendTail(sb);
		html = sb.toString();
		
		return html;
	}
	
}
